package org.bookr.console.controller;

import org.bookr.engine.model.*;
import org.bookr.engine.service.BookrService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.beans.PropertyEditorSupport;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Pawel Tomaszewski
 */
@Controller
public class CommentController {
    private BookrService bookrService;
    private Logger logger = LoggerFactory.getLogger(CommentController.class);

    @RequestMapping(value = "/comment/create", method = RequestMethod.GET)
    public ModelAndView createCommentForm() {
        ModelAndView result = new ModelAndView("console.createComment");
        result.addObject("status", "console.webapp.status.fillForm");
        result.addObject("comment", new Comment());
        result.addObject("allReaders", bookrService.listReaders());
        result.addObject("allBooks", bookrService.listBooks());
        return result;
    }

    @RequestMapping(value = "/comment/create", method = RequestMethod.POST)
    public ModelAndView processCreateCommentForm(@ModelAttribute Comment comment, BindingResult bindingResult) {
        ModelAndView results = new ModelAndView("console.createComment");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "title", "console.webapp.formValidation.emptyField");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "content", "console.webapp.formValidation.emptyField");
        if(bindingResult.hasErrors()) {
            results.addObject("status", "console.webapp.status.correctForm");
            results.addObject("allReaders", bookrService.listReaders());
            results.addObject("allBooks", bookrService.listBooks());
            logger.debug("There was some errors: " + bindingResult.getAllErrors());
        } else {
            Date now = new Date();
            comment.setCreatedDate(now);
            comment.setLastUpdateDate(now);
            String id = bookrService.updateComment(comment);
            results.addObject("status", "console.webapp.status.createSuccess");
            results.addObject("comment", bookrService.loadComment(id));
            results.setViewName("console.comment");
        }
        return results;
    }

    @RequestMapping(value = "/comment/{id}/edit", method = RequestMethod.GET)
    public ModelAndView editCommentForm(@PathVariable String id) {
        ModelAndView results = new ModelAndView("console.editComment");
        results.addObject("status", "console.webapp.status.fillForm");
        results.addObject("comment", bookrService.loadComment(id));
        results.addObject("allReaders", bookrService.listReaders());
        results.addObject("allBooks", bookrService.listBooks());
        return results;
    }

    @RequestMapping(value = "/comment/{id}/edit", method = RequestMethod.POST)
    public ModelAndView processEditCommentForm(@PathVariable String id,
                                               @ModelAttribute Comment comment, BindingResult bindingResult) {
        ModelAndView results = new ModelAndView("console.editComment");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "title", "console.webapp.formValidation.emptyField");
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "content", "console.webapp.formValidation.emptyField");
        if(bindingResult.hasErrors()) {
            results.addObject("status", "console.webapp.status.correctForm");
            results.addObject("allReaders", bookrService.listReaders());
            results.addObject("allBooks", bookrService.listBooks());
        } else {
            comment.setLastUpdateDate(new Date());
            bookrService.updateComment(comment);
            results.addObject("status", "console.webapp.status.editSuccess");
            results.addObject("comment", bookrService.loadComment(id));
            results.setViewName("console.comment");
        }
        return results;
    }

    @RequestMapping("/comments")
    public ModelAndView listComments() {
        ModelAndView results = new ModelAndView("console.comments");
        results.addObject("status", "console.webapp.status.ok");
        results.addObject("comments", bookrService.listComments());
        return results;
    }

    @RequestMapping("/comment/{id}")
    public ModelAndView showComment(@PathVariable String id) {
        ModelAndView results = new ModelAndView("console.comment");
        results.addObject("status", "console.webapp.status.ok");
        results.addObject("comment", bookrService.loadComment(id));
        return results;
    }

    @RequestMapping("/comment/{id}/remove")
    public ModelAndView removeComment(@PathVariable String id) {
        ModelAndView results = new ModelAndView("redirect:/comments");
        bookrService.removeComment(bookrService.loadComment(id));
        return results;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
        binder.registerCustomEditor(Book.class, "book", new PropertyEditorSupport(Book.class) {
            @Override
            public void setAsText(String id) {
                setValue(bookrService.loadBook(id));
            }
        });
        binder.registerCustomEditor(Reader.class, "reader", new PropertyEditorSupport(Reader.class) {
            @Override
            public void setAsText(String id) {
                setValue(bookrService.loadReaderById(id));
            }
        });
    }

    public BookrService getBookrService() {
        return bookrService;
    }

    public void setBookrService(BookrService bookrService) {
        this.bookrService = bookrService;
    }
}